home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Ham Radio 2000 #2
/
Ham Radio 2000 - Volume 2.iso
/
HAMV2
/
TCP_IP
/
TNOS230S
/
LOOK.C
< prev
next >
Wrap
C/C++ Source or Header
|
1997-09-06
|
7KB
|
262 lines
/* Peek into a user's actions on the bbs.
* This allows you to follow all stuff, and also
* send messages and initiate chats...
* (C) 1994, Johan. K. Reinalda, WG7J
*/
#include "global.h"
#ifdef LOOKSESSION
#include "ctype.h"
#include "commands.h"
#include "session.h"
#include "smtp.h"
#include "usock.h"
#include "mailbox.h"
#if !defined(_lint)
static char rcsid[] OPTIONAL = "$Id: look.c,v 1.17 1997/09/07 00:31:16 root Exp root $";
#endif
static void look_input (int unused,void *p1,void *p2);
extern int sockblock (int s,int value);
struct look {
struct session *sp; /* our look session */
int user; /* socket we look at */
};
int
dolook(int argc OPTIONAL, char *argv[],void *p OPTIONAL)
{
struct look lk;
struct usock *up;
int chat;
char *cp;
char const *cp2;
char name[20];
char buf[MBXLINE];
int i, block;
/* Check if this comes from console - WG7J*/
if (Curproc->input != Command->input)
return 0;
#ifdef MAILBOX
/* Find the user ! */
lk.user = atoi (argv[1]); /* store socket #, or illegal # if callsign */
for (i = 0; i < NUMMBX; i++) {
if (Mbox[i] == NULLMBX)
continue;
if (!stricmp (Mbox[i]->name, argv[1]))
break;
if (lk.user && Mbox[i]->user == lk.user)
break;
}
if (i != NUMMBX) {
lk.user = Mbox[i]->user;
strncpy (name, Mbox[i]->name, 20);
} else {
#endif
lk.user = atoi (argv[1]);
sprintf (name, "socket %d", lk.user);
#ifdef MAILBOX
}
#endif
if ((up = itop (lk.user)) == NULLUSOCK) {
tputs ("User socket error!\n");
return 0;
}
if (up->look) {
tprintf ("Already looking at %s\n", argv[1]);
return 0;
}
if (lk.user == Curproc->input || lk.user == Curproc->output) {
tputs ("Can not look at myself!\n");
return 0;
}
/* Now everything seems okay ! Get a session */
if ((lk.sp = newsession (name, LOOK, 1)) == NULLSESSION) {
tputs (TooManySessions);
return 0;
}
up->look = Curproc; /* Tell the socket to echo data to this process ! */
chat = 0;
block = sockblock (Curproc->input, SOCK_NORXBLOCK);
tprintf ("%s session %d looking at %s\n", Sestypes[lk.sp->type], lk.sp->index, argv[1]);
/* Process whatever's typed on the terminal */
memset (buf, 0, MBXLINE); /* Clear the input buffer */
while (nb_recvline (Curproc->input, (unsigned char *) buf, sizeof(buf) - 1) >= 0) {
if (itop (lk.user) == NULLUSOCK)
break;
if (buf[0] == '/') {
cp = skipnonwhite (buf);
cp = skipwhite (cp);
/* process commands */
switch (tolower (buf[1])) {
case 'h':
case '?':
#ifdef MAILBOX
tputs ("<Cmds>: /c-chat /i-insert /m-msg /q-quit\n");
#else
tputs ("<Cmds>: /q-quit\n");
#endif
break;
#ifdef MAILBOX
case 'm': /* Send a message to the user */
if (i == NUMMBX) /* Not a mailbox user */
break;
#if 0
cp = &buf[2];
if (buf[2] == ' ')
cp = &buf[3];
#endif
usprintf (lk.user, "<sysop>: %s", cp);
break;
case 'c': /* Initiate chat mode */
if (chat || i == NUMMBX)
/* Already in 'chat' mode or not a mailbox user */
break;
(void) usputs (lk.user, "*** SYSOP Initiated CHAT.\n");
up->look = NULL; /* Disable echoing in socket layer */
/* Now we need to redirect the network input
* from the user's bbs process to the chat process
*/
lk.sp->proc1 = newproc ("CHAT Server", 1024, look_input, 0,
(void *)&lk, NULL, 0);
chat = 1;
break;
#endif
case 'i':
#if 0
cp = skipnonwhite (buf);
cp = skipwhite (cp);
#endif
up->insertptr = up->insertbuf = strdup (cp);
(void) usputs (lk.user, cp);
break;
case 'b':
case 'e':
case 'q': /* quit chat mode, or look mode */
#ifdef MAILBOX
if (!chat)
goto done;
lk.sp->proc1 = NULLPROC;
up->look = Curproc; /* Enable echoing in socket layer */
(void) usputs (lk.user, "*** BACK in mailbox\n");
kpause (500);
kwait (NULL); /* wait for the death of look_input */
chat = 0;
#else
goto done;
#endif
break;
default:
break;
}
}
#ifdef MAILBOX
else if (chat)
usprintf (lk.user, "<sysop>: %s", buf);
#endif
usflush (lk.user);
usflush (Curproc->output);
memset (buf, 0, MBXLINE); /* Clear the input buffer */
}
done:
(void) sockblock (Curproc->input, block);
/* A 'close' command was given, or user disconnected.
* Notify the user, kill the receiver input task and wait for a response
* from the user before freeing the session.
*/
cp2 = sockerr (lk.sp->input);
tprintf ("\n%s session %u closed: %s\n", Sestypes[lk.sp->type], lk.sp->index,
(cp2 != NULLCHAR) ? cp2 : "EOF");
if ((up = itop (lk.user)) != NULLUSOCK) /* Make sure socket is still there */
up->look = NULL;
#ifdef MAILBOX
if (lk.sp->proc1 != NULLPROC) {
/* kill the receive process */
lk.sp->proc1 = NULLPROC;
if (up) {
(void) usputs (lk.user, "*** BACK in mailbox\n");
usflush (lk.user);
}
}
#endif
(void) keywait (NULLCHAR, 1);
freesession (lk.sp);
return 0;
}
#ifdef MAILBOX
/* Task that read the user's input socket (that formerly went to the socket
* process), and sends it to the look session !
*/
void
look_input(unused,p1,p2)
int unused OPTIONAL;
void *p1;
void *p2 OPTIONAL;
{
struct session *sp;
struct usock *up;
int user,c;
int block;
int done = 0;
sp = ((struct look *)p1)->sp;
user = ((struct look *)p1)->user;
if ((up = itop (user)) == NULLUSOCK) {
/* Make sure our parent doesn't try to kill us after we exit */
sp->proc1 = NULLPROC;
return;
}
/* Suspend the process that owns the socket */
suspend (up->owner);
/* Get current blocking mode and set to non-block */
block = sockblock (user, SOCK_NORXBLOCK);
/* Process input on the users socket connection */
while (!done) {
while ((c = recvchar (user)) == EOF) {
if (errno != EWOULDBLOCK || sp->proc1 == NULLPROC) {
done = 1;
break;
}
kpause (500);
}
if (!done)
tputc ((unsigned char)c);
}
if (sp->proc1 != NULLPROC)
tputs ("*** Remote user disconnected!\n");
/* Reset to original blocking mode */
(void) sockblock (user, block);
/* Make sure our parent doesn't try to kill us after we exit */
sp->proc1 = NULLPROC;
/* Alert the parent, in case the chat was terminated by losing the
* user connection. This in effect will close the look session
*/
alert (sp->proc, ENOTCONN);
/* Resume the process that owns the socket */
resume (up->owner);
}
#endif /* MAILBOX */
#endif /* LOOKSESSION */